import { Directive, OnInit, ElementRef, Input, Renderer2 } from '@angular/core'

@Directive({
  selector: '[v-loading]'
})
export class LoadingDirective implements OnInit {
  @Input() text: string // 加载时的提示文字
  @Input() lock: boolean = false // 全屏遮罩时，是否禁用滚动
  @Input('custom-class') customClass: string // 遮罩层的额外 class
  @Input('full-screen') fullScreen: boolean = false // 是否全屏显示遮罩
  @Input('v-loading-top') loadingTop: string = '50%' // loading 图标与顶部的距离
  @Input('v-loading') set showLoading(val: boolean) { // 是否显示
    this.visible = val
    if (!this.cacheElement) return
    this.cacheElement.innerHTML = this.makeHtml()
  }

  cacheElement: HTMLElement
  cacheOverflow: string
  private visible: boolean = false

  constructor(private el: ElementRef, private renderer: Renderer2) {}

  makeHtml(): string {
    this.lock && this.toggleLock(this.visible)
    return `
      <div class="v-loading-mask${this.customClass ? ' ' + this.customClass : ''}${this.fullScreen ? ' is-fullscreen' : ''}"
        style="display: ${this.visible ? 'block' : 'none'}">
        <div class="v-loading-spinner" style="top: ${this.loadingTop}">
          <svg class="circular" viewBox="25 25 50 50">
            <circle class="path" cx="50" cy="50" r="20" fill="none"/>
          </svg>
          <p class="v-loading-text" style="display: ${this.text ? 'block' : 'none'}">
            ${this.text}
          </p>
        </div>
      </div>
    `
  }

  toggleLock(status: boolean = false): void {
    if (!this.lock) return
    const nextValue = status ? 'hidden' : this.cacheOverflow
    this.renderer.setStyle(document.body, 'overflow', nextValue)
  }

  ngOnInit(): void {
    if (this.lock) {
      this.cacheOverflow = window.getComputedStyle(document.body).overflow
    }
    this.cacheElement = this.renderer.createElement('div')
    this.cacheElement.innerHTML = this.makeHtml()
    const parentElement = this.fullScreen ? document.body : this.el.nativeElement
    if (!this.fullScreen) {
      this.renderer.setStyle(this.el.nativeElement, 'position', 'relative')
    }
    this.renderer.appendChild(parentElement, this.cacheElement)
  }
}
